/*
 * JAXPTransformer.java
 *
 * Created on July 30, 2006, 11:49 PM
 *
 * (C) R. Alexander Milowski alex@milowski.com
 */

package org.infoset.xml.jaxp;

import java.util.Iterator;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import org.infoset.xml.InfosetFactory;
import org.infoset.xml.Item;
import org.infoset.xml.Item.ItemType;
import org.infoset.xml.ItemDestination;
import org.infoset.xml.Name;
import org.infoset.xml.XMLException;
import org.infoset.xml.filter.*;
import org.infoset.xml.filter.ItemFilter;
import org.infoset.xml.sax.SAXEventGenerator;
import org.infoset.xml.sax.SAXItemDestination;

/**
 *
 * @author R. Alexander Milowski
 */
public class TransformerFilter implements ItemFilter {

   DOMResult domResult;
   ItemDestination sink;
   Transformer xformer;
   SAXItemDestination saxSink;
   SAXTransformerFactory saxFactory;
   
   /** Creates a new instance of JAXPTransformer */
   public TransformerFilter(Transformer xformer,SAXTransformerFactory saxFactory) {
      this.xformer = xformer;
   }
   
   public void setParameter(Name name,Object value) {
      xformer.setParameter(name.getLocalName(),value);
   }
   
   public void attach(ItemDestination sink) {
      this.sink = sink;
   }
   
   public void send(Item item) 
      throws XMLException
   {
      if (item.getType()==ItemType.DocumentItem) {
         try {
            TransformerHandler saxHandler = saxFactory.newTransformerHandler();
            domResult = new DOMResult();
            saxHandler.setResult(domResult);
            saxSink = new SAXItemDestination(saxHandler);
         } catch (TransformerConfigurationException ex) {
            throw new XMLException("Cannot create sax handler to build DOM for transformer.",ex);
         }
      } else if (saxSink==null) {
         throw new IllegalStateException("No document item was send before item type "+item.getType());
      }
      saxSink.send(item);
      if (item.getType()==ItemType.DocumentEndItem) {
         SAXEventGenerator generator = new SAXEventGenerator();
         generator.setItemConstructor(InfosetFactory.getDefaultInfoset().createItemConstructor());
         generator.setItemDestination(sink);
         try {
            xformer.transform(new DOMSource(domResult.getNode()),new SAXResult(generator));
         } catch (TransformerException ex) {
            throw new XMLException("Transform failed.",ex);
         }
      }
   }
   
}
